<template>
  <div class="menus_box" v-loading="loading">
    <div class="menus_addbtn">
      <el-button icon="plus" @click="openAddMenuDialog(0)" type="primary">
        新增根菜单
      </el-button>
    </div>
    <el-table
      :data="menusData"
      row-key="id"
      border
      :row-style="{ height: '48px' }"
      :header-row-style="{ color: '#232324', fontWeight: 'bold' }"
    >
      <el-table-column align="center" prop="id" min-width="95" label="ID" />
      <el-table-column
        align="center"
        prop="title"
        min-width="120"
        label="展示名称"
      />
      <el-table-column align="center" prop="icon" min-width="130" label="图标">
        <template #default="scope">
          <div v-if="scope.row.icon" class="icon-column">
            <el-icon :size="16">
              <component :is="scope.row.icon" />
            </el-icon>
            <span>&nbsp;{{ scope.row.icon }}</span>
          </div>
        </template>
      </el-table-column>
      <el-table-column
        align="center"
        prop="name"
        min-width="150"
        label="路由Name"
      />
      <el-table-column
        align="center"
        prop="path"
        min-width="150"
        label="路由Path"
      />
      <el-table-column
        align="center"
        prop="component"
        min-width="260"
        label="组件路径"
      />
      <el-table-column
        align="center"
        prop="parentId"
        min-width="90"
        label="父节点"
      />
      <el-table-column align="center" prop="sort" min-width="70" label="排序" />
      <el-table-column
        align="center"
        prop="visible"
        min-width="100"
        label="是否隐藏"
      >
        <template #default="scope">
          <el-tag v-if="scope.row.visible == 1">显示</el-tag>
          <el-tag v-else type="danger">隐藏</el-tag>
        </template>
      </el-table-column>
      <el-table-column align="center" prop="type" min-width="100" label="类型">
        <template #default="scope">
          <el-tag v-if="scope.row.type == 1" type="success">菜单</el-tag>
          <el-tag v-else-if="scope.row.type == 2" type="warning">目录</el-tag>
          <el-tag v-else type="danger">外链</el-tag>
        </template>
      </el-table-column>
      <el-table-column
        align="center"
        prop="redirect"
        min-width="140"
        label="跳转路径"
      />
      <el-table-column
        align="center"
        prop="perm"
        min-width="130"
        label="标识"
      />
      <el-table-column
        align="center"
        label="创建时间"
        min-width="180"
        prop="createTime"
      />
      <el-table-column
        align="center"
        label="更新时间"
        min-width="180"
        prop="updateTime"
      />
      <el-table-column align="left" fixed="right" label="操作" width="300">
        <template #default="scope">
          <el-button
            type="primary"
            link
            icon="plus"
            @click="openAddMenuDialog(scope.row.id)"
          >
            添加子菜单
          </el-button>
          <el-button
            type="primary"
            link
            icon="edit"
            @click="editMenu(scope.row)"
          >
            编辑
          </el-button>
          <el-popconfirm
            :icon="InfoFilled"
            icon-color="#626AEF"
            width="180"
            title="是否删除该菜单?"
            @confirm="deleteMenu(scope.row.id)"
          >
            <template #reference>
              <el-button type="primary" link icon="delete">删除</el-button>
            </template>
          </el-popconfirm>
        </template>
      </el-table-column>
    </el-table>

    <el-dialog
      v-model="dialogFormVisible"
      :title="dialogTitle"
      style="min-width: 400px"
    >
      <el-form
        v-if="dialogFormVisible"
        ref="menuForms"
        :inline="true"
        :model="menuForm"
        :rules="rules"
        label-position="top"
        label-width="85px"
      >
        <el-form-item label="路由Name" prop="name" style="width: 40%">
          <el-input v-model="menuForm.name" placeholder="唯一英文字符串" />
        </el-form-item>
        <el-form-item prop="path" label="路由Path" style="width: 40%">
          <el-input v-model="menuForm.path" placeholder="输入路由Path" />
        </el-form-item>
        <el-form-item label="类型" prop="type" style="width: 40%">
          <el-select
            v-model="menuForm.type"
            clearable
            placeholder="选择菜单类型"
          >
            <el-option
              v-for="item in typeOptions"
              :key="item.value"
              :label="item.label"
              :value="item.value"
            />
          </el-select>
        </el-form-item>
        <el-form-item label="父节点ID" style="width: 30%">
          <el-cascader
            v-model="menuForm.parentId"
            style="width: 100%"
            :disabled="!isEdit"
            :options="menuOption"
            :props="{
              checkStrictly: true,
              label: 'title',
              value: 'id',
              disabled: 'disabled',
              emitPath: false,
            }"
            :show-all-levels="false"
            filterable
          />
        </el-form-item>
        <el-form-item label="组件路径" prop="component" style="width: 65%">
          <el-input
            v-model="menuForm.component"
            placeholder="请输入组件的相对位置（目录src）"
          />
        </el-form-item>
        <el-form-item label="标识" prop="perm" style="width: 30%">
          <el-input
            v-model="menuForm.perm"
            placeholder="输入菜单标识（推荐全大写）"
          />
        </el-form-item>
        <el-form-item label="展示标题" prop="title" style="width: 30%">
          <el-input v-model="menuForm.title" placeholder="展示标题不能为空" />
        </el-form-item>
        <el-form-item label="图标" prop="icon" style="width: 30%">
          <icon v-model:icon="menuForm.icon" style="width: 100%" />
        </el-form-item>
        <!-- <el-form-item label="重定向" prop="redirect" style="width: 30%">
          <el-input v-model="menuForm.redirect" placeholder=""/>
        </el-form-item> -->
        <el-form-item label="排序标记" prop="sort" style="width: 30%">
          <el-input-number v-model="menuForm.sort" :min="0" :max="100" />
        </el-form-item>
        <el-form-item label="是否显示" style="width: 40%">
          <el-switch
            v-model="menuForm.visible"
            active-text="显示"
            inactive-text="隐藏"
          />
        </el-form-item>
        <el-form-item label="缓存页面" style="width: 40%">
          <el-switch
            v-model="menuForm.keepAlive"
            active-text="YES"
            inactive-text="NO"
          />
        </el-form-item>
        <el-form-item label="自动关闭标签" style="width: 40%">
          <el-switch
            v-model="menuForm.closeTab"
            active-text="YES"
            inactive-text="NO"
          />
        </el-form-item>
        <el-form-item label="基础页面" style="width: 40%">
          <el-switch
            v-model="menuForm.defaultMenu"
            active-text="YES"
            inactive-text="NO"
          />
        </el-form-item>
      </el-form>
      <template #footer>
        <span class="dialog-footer">
          <el-button @click="dialogFormVisible = false">取消</el-button>
          <el-button type="primary" @click="formConfirm(menuForms)">
            提交
          </el-button>
        </span>
      </template>
    </el-dialog>
  </div>
</template>

<script setup lang="ts">
import { ref, onMounted, reactive } from 'vue'
import {
  reqAddMenu,
  reqChangeMenu,
  reqDeleteMenuById,
  reqGetMenuPage,
} from '@/api/menu'
import {
  MenuInfoPageParams,
  MenuInfoParams,
  MenuInfoRes,
} from '@/api/menu/type'
import { ElMessage, FormInstance } from 'element-plus'
import { InfoFilled } from '@element-plus/icons-vue'
import icon from '@/views/systemAdmin/menu/icon.vue'

onMounted(async () => {
  getMenuInofPage()
})

const loading = ref(false)
const total = ref(0)
const pageParams = reactive<MenuInfoPageParams>({
  pageNum: 1,
  pageSize: 999,
})

const dialogFormVisible = ref<boolean>(false)
const menuForms = ref<FormInstance>()
const menuForm = ref<MenuInfoParams>({
  id: 0,
  parentId: 0,
  name: '',
  type: 1,
  path: '',
  component: '',
  perm: '',
  title: '',
  visible: true,
  sort: 1,
  icon: 'aim',
  keepAlive: false,
  closeTab: false,
  defaultMenu: false,
  redirect: '',
})

const menusData = ref<MenuInfoRes[]>([])

const getMenuInofPage = async () => {
  loading.value = true
  try {
    const { data } = await reqGetMenuPage(pageParams)
    menusData.value = data.list
    total.value = data.total
  } catch (erro) {
    ElMessage.error((erro as Error).message)
  } finally {
    loading.value = false
  }
}

const typeOptions = [
  {
    value: 1,
    label: '菜单',
  },
  {
    value: 2,
    label: '目录',
  },
  {
    value: 3,
    label: '外链',
  },
]
const rules = reactive({
  name: [{ required: true, message: '请输入菜单name', trigger: 'blur' }],
  path: [{ required: true, message: '请输入菜单path', trigger: 'blur' }],
  component: [{ required: true, message: '请输入组件路径', trigger: 'blur' }],
  type: [{ required: true, message: '请选择类型', trigger: 'blur' }],
  title: [{ required: true, message: '请输入菜单标题', trigger: 'blur' }],
  perm: [{ required: true, message: '请输入菜单标识', trigger: 'blur' }],
})

interface menuOptionType {
  id: number
  title: string
}
const menuOption = ref<menuOptionType[]>([
  {
    id: 0,
    title: '根菜单',
  },
])
const setOptions = () => {
  menuOption.value = [
    {
      id: 0,
      title: '根目录',
    },
  ]
  setMenuOptions(menusData.value, menuOption.value, false)
}
const setMenuOptions = (
  menuData: MenuInfoRes[],
  optionsData: menuOptionType[],
  disabled: boolean,
) => {
  menuData &&
    menuData.forEach((item) => {
      if (item.children && item.children.length) {
        const option = {
          title: item.title,
          id: item.id,
          disabled: disabled || item.id === menuForm.value.id,
          children: [],
        }
        setMenuOptions(
          item.children,
          option.children,
          disabled || item.id === menuForm.value.id,
        )
        optionsData.push(option)
      } else if (true) {
        const option = {
          title: item.title,
          id: item.id,
          disabled: disabled || item.id === menuForm.value.id,
        }
        optionsData.push(option)
      }
    })
}

// 添加菜单方法，id为 0则为添加根菜单
const isEdit = ref(false)
const dialogTitle = ref('新增菜单')

const openAddMenuDialog = (id: number) => {
  dialogTitle.value = '新增菜单'
  isEdit.value = false
  if (menuForm.value.id !== 0) {
    resetMenuForm()
  }
  menuForm.value.parentId = id
  setOptions()
  dialogFormVisible.value = true
}
// 修改菜单方法
const editMenu = async (data: MenuInfoRes) => {
  if (data.type === 1) {
    dialogTitle.value = '编辑菜单'
  } else if (data.type === 2) {
    dialogTitle.value = '编辑目录'
  } else {
    dialogTitle.value = '编辑外链'
  }

  menuForm.value = data as MenuInfoParams
  isEdit.value = true
  setOptions()
  dialogFormVisible.value = true
}

const addMenu = async () => {
  try {
    const { message } = await reqAddMenu(menuForm.value)
    resetMenuForm()
    getMenuInofPage()
    ElMessage.success(message)
  } catch (error) {
    ElMessage.error((error as Error).message)
  }
}

const udpateMenu = async () => {
  try {
    const { message } = await reqChangeMenu(menuForm.value)
    ElMessage.success(message)
    getMenuInofPage()
  } catch (error) {
    ElMessage.error((error as Error).message)
  }
}

const formConfirm = async (formEl: FormInstance | undefined) => {
  if (!formEl) return
  await formEl.validate((valid) => {
    if (valid) {
      if (isEdit.value) {
        udpateMenu()
      } else {
        addMenu()
      }
      dialogFormVisible.value = false
    }
  })
}
const deleteMenu = async (id: number) => {
  try {
    const { message } = await reqDeleteMenuById(id)
    ElMessage.success(message)
    await getMenuInofPage()
  } catch (error) {
    ElMessage.error((error as Error).message)
  }
}

const resetMenuForm = () => {
  menuForm.value = {
    id: 0,
    parentId: 0,
    name: '',
    type: 1,
    path: '',
    component: '',
    perm: '',
    title: '',
    visible: true,
    sort: 1,
    icon: 'aim',
    keepAlive: false,
    closeTab: false,
    defaultMenu: false,
    redirect: '',
  }
}
</script>
<style scoped lang="scss">
.menus_box {
  padding: 24px;

  .menus_addbtn {
    margin-bottom: 12px;
    display: flex;
  }

  .icon-column {
    display: flex;
    align-items: center;
    justify-content: center;
  }
}
</style>
